#ifdef BUILD
	#define TYPE _declspec(dllexport)
#else
	#define TYPE
#endif

#define CHANNEL_CHAT								0x4CA
#define CHANNEL_JOIN								0x4B5
#define CHANNEL_LEAVE								0x4B8
#define CHANNEL_LIST								0z4BD
#define CHANNEL_LISTSTART							0x4BB
#define CHANNEL_REQUEST_CHAT						0x4C9
#define CHANNEL_REQUESTPLAYERLIST					0x4C5
#define CHANNEL_RESPONSE_RULE						0x4CF
#define CHANNEL_RESPONSEJOIN						0x4B7
#define CHANNEL_RESPONSEPLAYERLIST					0x4C6
#define CLOCK_SYNCHRONIZE							0x169
#define GUNZPACKET_COMMAND_VERSION					0x38
#define GUNZPACKET_DATA_HEADER_SIZE					5
#define GUNZPACKET_DECRYPTED						0x64
#define GUNZPACKET_ENCRYPTED						0x65
#define GUNZPACKET_HEADER_SIZE						6
#define GUNZPACKET_KEY_EXCHANGE						0x0A
#define MATCH_ANNOUNCE								0x192
#define MATCH_BROADCAST_DUELINTERRUPTVICTORIES		0x89B
#define MATCH_BROADCAST_DUELRENEWVICTORIES			0x89A
#define MATCH_LOGIN									0x3E9
#define MATCH_REQUESTACCOUNTCHARLIST				0x6A5
#define MATCH_REQUESTCREATECHAR						0x6AF
#define MATCH_REQUESTDELETECHAR						0x6B1
#define MATCH_REQUESTSELECTCHAR						0x6A7
#define MATCH_RESPONSE_RESULT						0x193
#define MATCH_RESPONSEACCOUNTCHARLIST				0x6A6
#define MATCH_RESPONSECREATECHAR					0x6B0
#define MATCH_RESPONSEDELETECHAR					0x6B2
#define MATCH_RESPONSESELECTCHAR					0x6A8
#define MATCH_RESPONSELOGIN							0x3EA
#define MATCH_WHISPER								0x641
#define MATCHSERVER_REQUESTRECOMMENDEDCHANNEL		0x4B1
#define MATCHSERVER_RESPONSERECOMMENDEDCHANNEL		0x4B2
#define NET_PING									0x142
#define NET_PONG									0x143
#define RESPONSE_ACCOUNT_IN_USE						10001
#define RESPONSE_AUTHENTICATION_FAILED				10005
#define RESPONSE_BANNED								10004
#define RESPONSE_CHANNEL_CANNOT_ENTER				30020
#define RESPONSE_CHANNEL_HAS_LEVEL_21_CHARACTER		30023
#define RESPONSE_CHANNEL_INVALID_LEVEL				30022
#define RESPONSE_CHANNEL_IS_FULL					30021
#define RESPONSE_CHARACTER_DOESNT_EXIST				10110
#define RESPONSE_CHARACTER_IN_CLAN_OR_CASH_ITEMS	10111
#define RESPONSE_INVALID_PASSWORD					10000
#define RESPONSE_INVALID_VERSION					10002
#define RESPONSE_NAME_EMPTY							10104
#define RESPONSE_NAME_IN_USE						10100
#define RESPONSE_NAME_INVALID_CHARACTERS			10101
#define RESPONSE_NAME_TOO_LONG						10103
#define RESPONSE_NAME_TOO_SHORT						10102
#define RESPONSE_OK									0
#define RESPONSE_SERVER_IS_FULL						10003
#define RESPONSE_STAGE_NOT_FOUND					30006
#define SIZE_1K										1024
#define SIZE_64K									65536
#define STAGE_CREATE								0x515
#define STAGE_JOIN									0x517
#define STAGE_LEAVE									0x51B
#define STAGE_LIST									0x522
#define STAGE_REQUESTJOIN							0x518
#define STAGE_REQUESTPRIVATEJOIN					0x519
#define STAGE_RESPONSEJOIN							0x51A

extern "C"
{
	bool TYPE IsConnected();
	bool TYPE IsInChannel();
	bool TYPE IsLoggedIn();

	char TYPE *GetChannelName();
	char TYPE *GetChannelRule();
	char TYPE *GetCharacterClanName();
	char TYPE *GetCharacterName();
	char TYPE *GetINIContents();
	char TYPE *GetPassword();
	char TYPE *GetServerIP();
	char TYPE *GetServerName();
	char TYPE GetServerType();
	char TYPE *GetUsername();

	class TYPE GunZPacket
	{
		private:
			unsigned char packet[SIZE_64K];
			unsigned short index;

		public:
			GunZPacket();

			unsigned char *GetPacket();
			unsigned char GetPacketID();
			unsigned short GetChecksum();
			unsigned short GetCommandID();
			unsigned short GetDataSize();
			unsigned short GetPacketSize();
			unsigned short GetType();

			void CalculateChecksum(unsigned short size);
			void Encrypt(unsigned char *key);
			void Decrypt(unsigned char *key);
			void FillPacket(unsigned char *buf, unsigned short size);
			void GetBytes(unsigned char *buf, unsigned short size);
			void ResetIndex();
			void SetCommandID(unsigned short id);
			void SetDataSize(unsigned short size);
			void SetPacketID(unsigned char id);
			void SetPacketSize(unsigned short size);
			void SetType(unsigned short type);
			void WriteBytes(unsigned char *buf, unsigned short size);
	};

	class TYPE TCPSocket
	{
		private:
			int sock;

		public:
			~TCPSocket();

			int Close();
			int Connect(char *ip, unsigned short port);
			int GetLastError();
			int Receive(char *buf, int size);
			int Send(char *buf, int size);

			TCPSocket();
	};

	class TYPE WS2
	{
		public:
			~WS2();
			WS2();
	};

	int TYPE ChannelChat(unsigned long player_id, unsigned long channel_id, char *buf);
	int TYPE CreateCharacter(unsigned long player_id, unsigned int index, char *name, unsigned int sex, unsigned int hair, unsigned int face, unsigned int costume);
	int TYPE CreateRoom(unsigned long player_id, char *name, bool private_room, char *password);
	int TYPE DeleteCharacter(unsigned long player_id, unsigned int index, char *name);
	int TYPE GetChannelPlayerList(unsigned long player_id, unsigned long channel_id, int page);
	int TYPE GetChannelType();
	int TYPE GetCharacterList();
	int TYPE GetMD5Size();
	int TYPE GetRecommendedChannel();
	int TYPE JoinChannel(unsigned long player_id, unsigned long channel_id);
	int TYPE JoinPrivateRoom(unsigned long player_id, unsigned long room_id, char *password);
	int TYPE JoinRoom(unsigned long player_id, unsigned long room_id);
	int TYPE Login(char *username, char *password, unsigned long long checksum, unsigned char *md5, unsigned short size);
	int TYPE Pong(unsigned int time);
	int TYPE SelectCharacter(unsigned long player_id, unsigned int index);

	TCPSocket TYPE *GetMatchSocket();

	unsigned char TYPE GetCharacterFace();
	unsigned char TYPE GetCharacterHair();
	unsigned char TYPE GetCharacterIndex();
	unsigned char TYPE GetCharacterLevel();
	unsigned char TYPE GetCharacterSex();
	unsigned char TYPE GetCurrentPacketID();
	unsigned char TYPE *GetKey();
	unsigned char TYPE *GetMD5();
	unsigned char TYPE GetPlayerPGrade();
	unsigned char TYPE GetPlayerUGrade();
	unsigned int TYPE GetCharacterBP();
	unsigned int TYPE GetCharacterClanGrade();
	unsigned int TYPE GetCharacterXP();
	unsigned long TYPE GetChannelID();
	unsigned long TYPE GetPlayerID();
	unsigned long long TYPE GetChecksum();
	unsigned short TYPE GetCharacterMaxAP();
	unsigned short TYPE GetCharacterMaxHP();
	unsigned short TYPE GetServerPort();

	void TYPE CopySubstring(char *input, char *from, char *to, char *output);
	void TYPE ExtractFromINI(char *ini_contents, char *section, char *element, char *buf);
	void TYPE GetProgramDirectory(char *buf, int size);
	void TYPE Print(char *buf, ...);
	void TYPE SetChannelID(unsigned long id);
	void TYPE SetChannelName(char *name);
	void TYPE SetChannelRule(char *rule);
	void TYPE SetChannelType(int type);
	void TYPE SetCharacterBP(unsigned int bp);
	void TYPE SetCharacterClanGrade(unsigned int grade);
	void TYPE SetCharacterClanName(char *name);
	void TYPE SetCharacterFace(unsigned char face);
	void TYPE SetCharacterHair(unsigned char hair);
	void TYPE SetCharacterIndex(unsigned char index);
	void TYPE SetCharacterLevel(unsigned char level);
	void TYPE SetCharacterMaxAP(unsigned short max_ap);
	void TYPE SetCharacterMaxHP(unsigned short max_hp);
	void TYPE SetCharacterName(char *name);
	void TYPE SetCharacterSex(unsigned char sex);
	void TYPE SetCharacterXP(unsigned int xp);
	void TYPE SetChecksum(unsigned long long checksum);
	void TYPE SetConnected(bool status);
	void TYPE SetCurrentPacketID(unsigned char id);
	void TYPE SetInChannel(bool status);
	void TYPE SetINIContents(char *buf);
	void TYPE SetKey(unsigned char *key);
	void TYPE SetLoggedIn(bool status);
	void TYPE SetMatchSocket(TCPSocket *match);
	void TYPE SetMD5(unsigned char *md5);
	void TYPE SetMD5Size(int size);
	void TYPE SetPassword(char *password);
	void TYPE SetPlayerID(unsigned long id);
	void TYPE SetPlayerPGrade(unsigned char pgrade);
	void TYPE SetPlayerUGrade(unsigned char ugrade);
	void TYPE SetServerIP(char *ip);
	void TYPE SetServerName(char *name);
	void TYPE SetServerPort(unsigned short port);
	void TYPE SetServerType(char type);
	void TYPE SetUsername(char *username);
}